package com.cocolover2.andbase.media;

import android.content.Context;
import android.media.AudioManager;
import android.os.Build;
import android.support.annotation.NonNull;

/**
 * 语音模式控制
 * MODE_NORMAL: 普通模式,既不是铃声模式也不是通话模式(播放音乐)
 * MODE_RINGTONE:铃声模式
 * MODE_IN_CALL:通话模式
 * MODE_IN_COMMUNICATION:通信模式,包括音/视频,VoIP通话.(3.0加入的,与通话模式类似)
 * (通话模式的情况下，听筒和扬声器切换才有效，其他模式关不关扬声器都一样)
 */
public class AudioHelper {

    private AudioManager mAudioManager;

    private AudioHelper() {
    }

    private static class AudioHelperHolder {
        private final static AudioHelper INSTANCE = new AudioHelper();
    }

    public static AudioHelper getInstance() {
        return AudioHelperHolder.INSTANCE;
    }


    public void setAudioModel(@NonNull Context context, int mode) {
        checkAudioManager(context);
        mAudioManager.setMode(mode);
    }

    /**
     * 切换到耳机模式
     */
    public void changeToHeadset(@NonNull Context context) {
        checkAudioManager(context);
        mAudioManager.setSpeakerphoneOn(false);
    }

    /**
     * 切换到外放(通话模式)
     *
     * @param context Context
     */
    public void changeToSpeaker(@NonNull Context context) {
        checkAudioManager(context);
        mAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
        mAudioManager.setSpeakerphoneOn(true);
    }

    /**
     * 切换到听筒(通话模式)
     */
    @SuppressWarnings("all")
    public void changeToReceiver(@NonNull Context context) {
        checkAudioManager(context);
        mAudioManager.setSpeakerphoneOn(false);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
            mAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
        } else {
            mAudioManager.setMode(AudioManager.MODE_IN_CALL);
        }
    }


    /**
     * 切换麦克风状态
     */
    public void changeMicrophoneState(Context context, boolean isMicrophoneMute) {
        checkAudioManager(context);
        mAudioManager.setMicrophoneMute(isMicrophoneMute);
    }

    public void changeSpeakerState(Context context, boolean isSpeakerphoneOn) {
        checkAudioManager(context);
        mAudioManager.setSpeakerphoneOn(isSpeakerphoneOn);
    }


    /**
     * 麦克风是否打开
     */
    public boolean isMicrophoneState(@NonNull Context context) {
        checkAudioManager(context);
        return mAudioManager != null && mAudioManager.isMicrophoneMute();
    }

    public boolean isSpeakerOn(@NonNull Context context) {
        checkAudioManager(context);
        return mAudioManager != null && mAudioManager.isSpeakerphoneOn();
    }

    public void changeToDefault(Context context) {
        checkAudioManager(context);
        mAudioManager.setMode(AudioManager.MODE_NORMAL);
        mAudioManager.setSpeakerphoneOn(true);
    }

    /**
     * 获取音频焦点
     *
     * @param context      context
     * @param streamType   the main audio stream type affected by the focus request
     * @param durationHint use {@link AudioManager#AUDIOFOCUS_GAIN_TRANSIENT} to indicate this focus request
     *                     is temporary, and focus will be abandonned shortly. Examples of transient requests are
     *                     for the playback of driving directions, or notifications sounds.
     *                     Use {@link AudioManager#AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK} to indicate also that it's ok for
     *                     the previous focus owner to keep playing if it ducks its audio output.
     *                     Alternatively use {@link AudioManager#AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE} for a temporary request
     *                     that benefits from the system not playing disruptive sounds like notifications, for
     *                     usecases such as voice memo recording, or speech recognition.
     *                     Use {@link AudioManager#AUDIOFOCUS_GAIN} for a focus request of unknown duration such
     *                     as the playback of a song or a video.
     * @param listener     焦点状态切换回调
     * @return true 获取成功
     */
    public boolean requestAudioFocus(Context context, int streamType, int durationHint, AudioManager.OnAudioFocusChangeListener listener) {
        checkAudioManager(context);
        return mAudioManager.requestAudioFocus(listener, streamType, durationHint) == AudioManager.AUDIOFOCUS_REQUEST_GRANTED;
    }

    /**
     * 释放音频焦点
     *
     * @param context  context
     * @param listener 焦点状态切换回调
     */
    public void abandAudioFoucs(Context context, AudioManager.OnAudioFocusChangeListener listener) {
        checkAudioManager(context);
        mAudioManager.abandonAudioFocus(listener);
    }

    private void checkAudioManager(Context context) {
        if (mAudioManager == null) {
            mAudioManager = (AudioManager) context.getApplicationContext().getSystemService(Context.AUDIO_SERVICE);
        }

    }
}
